#ifndef __AS_SCREEN__H__
#define __AS_SCREEN__H__

/*
 *	including head files
 */
#include "..\control\ASControl.h"
#include "..\control\ASImage.h"
#include "..\app\ASAppLayout.h"
#include "..\tool\ASLog.h"
/*
 *	definition
 */
#define AS_SCREEN_MAX_CTRL_COUNTS           24



typedef enum
{
    AS_SCREEN_LOADING,
    AS_SCREEN_CONTENT,
    AS_SCREEN_OPTION,
    AS_SCREEN_DETAIL,
    AS_SCREEN_HELP,
    AS_SCREEN_MORE_INFO,
    AS_SCREEN_CONFIRM,
    AS_SCREEN_POPUP,
    AS_SCREEN_WAITING,
    AS_SCREEN_NUMBER,
    AS_SCREEN_DATETIME,
    AS_SCREEN_CUSTOM,

    AS_SCREEN_FTDATA,
    AS_SCREEN_FTTYPE,
    AS_SCREEN_FTDETAIL,
    AS_SCREEN_FTSTAT,
    AS_SCREEN_FTSTAT_SUB,
    AS_SCREEN_FTSETTING,
    AS_SCREEN_FTSETTING_SUB,
    AS_SCREEN_FTABOUT,
    AS_SCREEN_FTABOUT_SUB,

    AS_SCREEN_TEST,//for test
    AS_SCREEN_TYPE_MAX
} as_screen_type;

struct _as_screen;
typedef struct _as_screen as_screen;

typedef void (*as_paint_hdlr)(as_screen* screen_p);//paint method of this screen
typedef void (*as_flush_hdlr)(as_screen* screen_p);//flush the data of screen for display
typedef void (*as_repaint_hdlr)(as_screen* screen_p);//for the case that current screen is small screen
typedef as_ret (*as_screen_init_hdlr)(as_screen* screen_p, as_screen_type screen_type);
typedef as_ret (*as_screen_deinit_hdlr)(as_screen* screen_p);

struct _as_screen
{
    /*attributes*/
    ASINT is_inited;
    ASINT is_small_screen;
    as_screen_type screen_type;
    ASINT screen_id;
    as_rect area;
    as_rect invalid_area;
    as_image* bg_img;
    ASINT bg_color;
    //first created controls will be covered by last created ones.
    ASINT ctrl_stack_top;
    as_control* ctrl_stack[AS_SCREEN_MAX_CTRL_COUNTS];
    /*methods*/
    //system event handled by main function(as_handle_sysevt)

    /*
     *	[description] key event handler of screen_p
     *  [param] screen_p : which screen
     *  [param] event : key event
     *  [param] keycode : key code
     *  screen will call its controls to handle this event.
     */
    void (*keyevt_hdlr)(as_screen* screen_p, ASINT event, ASINT keycode);

    /*
     *	[description] pen event handler of screen_p
     *  [param] screen_p : which screen
     *  [param] event : key event
     *  [param] x : position
     *  [param] y : position
     *  screen will call its controls to handle this event.
     */
    void (*penevt_hdlr)(as_screen* screen_p, ASINT event, ASINT x, ASINT y);

    /*
     *	[description] paint handler of screen_p
     *  [param] screen_p : which screen
     *  as_screen_paint.
     *  screen paint function depend on <painter's algorithm>.
     */
    void (*paint_hdlr)(as_screen* screen_p);

    /*
     *	[description] paint handler of screen_p
     *  [param] screen_p : which screen
     *  as_screen_repaint.
     *  also deal the repaint case of small screen
     */
    void (*repaint_hdlr)(as_screen* screen_p);

    /*
     *	[description] flush the content of screen to lcd
     *  [param] screen_p : which screen
     *  as_screen_flush
     */
    void (*flush_hdlr)(as_screen* screen_p);

    /*
     *	[description] initialize of a new screen
     *  [param] screen_p : which screen
     *  [param] screen_type : which type of screen , it will call detail screen
     *  [return] as_ret : AS_OK or error code.
     */
    as_ret (*init_hdlr)(as_screen* screen_p, as_screen_type screen_type);

    /*
     *	[description] deinit of an existent screen
     *  [param] screen_p : which screen
     *  [return] as_ret : AS_OK or error code.
     */
    as_ret (*deinit_hdlr)(as_screen* screen_p);

    /*
     *	[description] pause when a screen pushed in stack by a new screen
     *  [param] screen_p : which screen
     *  [return] as_ret : AS_OK or error code.
     */
    as_ret (*pause)(as_screen* screen_p);

    /*
     *	[description] resume when a screen pop to stack top
     *  [param] screen_p : which screen
     *  [return] as_ret : AS_OK or error code.
     */
    as_ret (*resume)(as_screen* screen_p);

    /*
     *	[description] add a control into the screen
     *  [param] screen_p : which screen
     *  [param] screen_type : which type of screen , it will call detail screen
     *  [param] paint_buf : which display buffer you want to show this control
     *  [param] area : display area of this control
     *  [param] exta_param_cnts : parameter counts for add this control
     *  [param] exta_param_p : detail parameters
     *  [return] as_control* : return the pointer if add ok, else return NULL.
     */
    as_control* (*add_ctrl)(as_screen* screen_p,
                            as_control_type type, as_rect area,
                            ASINT exta_param_cnts, void* exta_param_p[]);

    /*
     *	[description] delete control through it's pointer
     *  [param] screen_p : which screen
     *  [param] ctrl_p : which control you want to delete
     *  [return] as_ret : AS_OK or error code.
     */
    as_ret (*delete_ctrl)(as_screen* screen_p, as_control* ctrl_p);

    /*
     *	[description] delete controls by type in screen
     *  [param] screen_p : which screen
     *  [param] ctrl_p : which type of controls you want to delete
     *  [return] as_ret : AS_OK or error code.
     */
    as_ret (*delete_ctrl_by_type)(as_screen* screen_p, as_control_type type);

    /*
     *	[description] cleat control stack of the screen
     *  [param] screen_p : which screen
     *  [return] as_ret : AS_OK or error code.
     */
    as_ret (*clear_ctrl_stack)(as_screen* screen_p);

    /*
     *	[description] get valid control counts of the screen
     *  [param] screen_p : which screen
     *  [return] ASINT : valid control counts.
     */
    ASINT (*get_ctrl_counts)(as_screen* screen_p);

    /*
     *	[description] set background color of the screen
     *  [param] screen_p : which screen
     *  [param] color : which color
     *  [return] as_ret : AS_OK or error code.
     */
    as_ret (*set_bg_color)(as_screen* screen_p, ASINT color);

    /*
     *	[description] set background image of the screen
     *  [param] screen_p : which screen
     *  [param] path : image path in ucs2
     *  [param] type : image type(from resource or from file)
     *  [return] as_ret : AS_OK or error code.
     */
    as_ret (*set_bg_image)(as_screen* screen_p, ASWSTR path, as_image_src_type type);

    void (*clear)(void);

    void (*goback)(ASINT if_draw);
};


//only called in screen stack
as_ret as_screen_init(as_screen* screen_p, as_screen_type screen_type);
as_ret as_screen_deinit(as_screen* screen_p);


/*
 *	[description] check the screen if small by given screen type
    [return] TRUE : given type belongs small screen
             FALSE : not small screen
 */
ASINT as_screen_is_small_screen(as_screen_type type);


as_screen* as_screen_calloc(as_screen_type type);
#endif//__AS_SCREEN__H__